<?php
namespace App\Admin\Actions;


use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\SoftDeletes;

/**
 * 后台通用恢复功能
 */
trait SoftDelete
{

	/**
	 * 数据批量恢复
	 */
	public function restore(Request $request, ActionSetter $setter)
	{
		$this->__soft_delete_check();

		// 默认配置器与自定义配置器
		$this->setRestoreDefaultSetter($setter);
		if( method_exists($this, 'actionRestore') ){
			$this->actionRestore($setter);
		}

		$allowBatch = $setter->call('batch');
		$id = $setter->call('get_ids', $request);

		// 获得格式化的ID
		$id = $this->__restore_format_id($id, $allowBatch);

		// 查询出要恢复的数据
		$models = $setter->call('find', $id);
		abort_unless($models, 403, '要恢复的数据不存在或状态异常');

		// 前置操作
		$setter->call('before', $models);

		// 恢复的真实操作
		$setter->call('handle', $models);

		return [
			'code' => 0,
			'message' => 'success',
			'data' => $models->count()
		];
	}

	private function setRestoreDefaultSetter($setter)
	{
		// 是否允许批量恢复
		$setter->batch(function(){
			return true;
		});

		// 获得要恢复的ID
		$setter->get_ids(function($request){
			if( $request->route()->hasParameter('id') ){ // Illuminate\Routing\Route
				return $request->route('id');
			}else{
				return $request->input('id');
			}
		});

		// 查询出要恢复的数据
		$setter->find(function($id){
			return $this->modelName()::withTrashed()->find($id);
		});

		// 恢复的真实操作
		$setter->handle(function($eloquent){
			if ($eloquent instanceof Model) {
				return $eloquent->restore();
			}else{
				return $eloquent->each(function($model){
					$model->restore();
				});
			}
		});
	}

	/**
	 * 如果allowBatch为true，返回数组，反之返回字符串
	 * 如果禁止
	 */
	private function __restore_format_id($id, bool $allowBatch)
	{
		if( $allowBatch ){
			$id = is_array($id) ? $id : [$id] ;
		}elseif( !$allowBatch && is_array($id) ){
			abort_if(count($id)!=1, 403, '不支持批量删除');
			$id = $id[0] ;
		}
		return $id;
	}

	private function __soft_delete_check()
	{
		abort_unless(method_exists($this, 'modelName'), 500, "未设置 modelName() 方法");
		$model = new ($this->modelName())();
		abort_unless(in_array(SoftDeletes::class, class_uses($model)), 500, "{$this->modelName()}未使用 SoftDeletes trait, 不支持恢复");
		unset($model);
	}

	/**
	 * 物理删除
	 */
	public function forceDelete(Request $request)
	{
		$this->__soft_delete_check();

		return [
			'code' => 0,
		];
	}
}

